﻿/// File: ApplicationHelper.cs 
/// Date: 03/15/2012
/// Author: Phil Allison (stoneguard@gmail.com)
/// Purpose: These are general support functions wrapped within a class in the base namespace for this library
/// 
/// copyright (c) 2001-2012, Phil Allison. Under the MIT License http://www.opensource.org/licenses/mit-license.php  
/// Feel free to reuse and modify this code as long as credit is given to the original author.
/// Modified code must be noted in this section.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.Configuration;
using System.IO;

namespace sgsBase
{
    /// <summary>
    /// ApplicationHelper - This class provides some general static functions to help with data manipulation
    /// </summary>
	public class ApplicationHelper
	{
        public static List<DbThreadHolder> DbConnThreads; // list of database connection threads.
        private static string _physicalPath = ""; // used to store the physical path of the application
        private static string _defaultDB = "";
		private static string _siteTitle = "";
		private static string _cookieGroup = "";
		private static string _loginCookie = "";
		private static string _defaultMailTemplate = "";
		private static string _baseUrl = "";
        /// <summary>
        /// CfgGetName - Gets the data value from the App.config file for the specified variable name 
        /// </summary>
        /// <param name="name">name of the value being retrieved from the configuration file</param>
        /// <returns>string containing the value of the given name</returns>
		public static string CfgGetAppSetting(string name)
		{
			return ConfigurationManager.AppSettings.Get(name);
		}

		public static string SiteTitle
		{
			get
			{
				if (_siteTitle == "")
					_siteTitle = CfgGetAppSetting("SiteTitle");

				return _siteTitle;
			}
		}

		public static string CookieGroup
		{
			get
			{
				if (_cookieGroup == "")
					_cookieGroup = CfgGetAppSetting("CookieGroup");

				return _cookieGroup;
			}
		}

		public static string LoginCookie
		{
			get
			{
				if (_loginCookie == "")
					_loginCookie = CfgGetAppSetting("LoginCookie");

				return _loginCookie;
			}
		}

		public static string BaseUrl
		{
			get
			{
				if (_baseUrl == "")
				{
					_baseUrl = CfgGetAppSetting("BaseUrl");
					if (_baseUrl.ToLower().StartsWith("http") == false)
						_baseUrl = "http://" + _baseUrl;
				}
				return _baseUrl;
			}
		}

		public static string AccountUrl
		{
			get
			{
				return BaseUrl + "/Account/";
			}
		}

		/// <summary>
		/// Retrieve database connection strings from the application config file
		/// </summary>
		/// <param name="dbPrefix"></param>
		/// <returns>Disctionary of DbConnectors, each referenced by its string</returns>
		/// Connection Strings are stored in the <configuration><ConnectionString> portion of the config file (app.config or web.config
		/// Below is an example:
		/// <connectionStrings>
		///		<add name="conn-live_test"
		///			connectionString="User Id=sa;Password=sa;server=localhost;data source=.\SQLEXPRESS;persist security info=False;initial catalog=live_test"
		///			providerName="System.Data.SqlClient" />
		///		...
		///	Generally, the connection name is prefixed with a database set name conn- representing production, and dev- representing development
		///	providerName is the type of driver being used for the connection
		///	the prefix is specified in the <appSettings> of the config by the key DB_Environment e.g. <add key="DB_Environment" value="conn-"/>
        public static Dictionary<string, DbConnector> CfgGetConnections(string dbPrefix)
        {
            Dictionary<string, DbConnector> connStrings = new Dictionary<string, DbConnector>();
            DbConnector dbc;
            foreach (ConnectionStringSettings css in ConfigurationManager.ConnectionStrings)
            {
                if (css.Name.StartsWith(dbPrefix))
                {
                    dbc = new DbConnector();
                    dbc.ConnectionString = css.ConnectionString;
					connStrings.Add(css.Name.Replace(dbPrefix, ""), dbc);
                }
            }

            return connStrings;
        }

		/// <summary>
		/// Get a list of all databases defined in the current connections as per the specified prefix.
		/// </summary>
		/// <returns>string[] - list of names of database connections</returns>
		public static string[] ConnectionStrings()
		{
			List<string> lstr = new List<string>();

			foreach (ConnectionStringSettings css in ConfigurationManager.ConnectionStrings)
			{
				if (css.Name.StartsWith(DbConnections.DBPrefix))
				{
					lstr.Add(css.Name.Replace(DbConnections.DBPrefix, ""));
				}
			}

			return lstr.ToArray();
		}

        /// <summary>
        /// PhysicalPath - return the physical path of the executable. This helps in figuring out relative pathing when needed
        /// </summary>
        /// final format of the pathname should be similar to c:\\somefolder\\bin\\
        public static string PhysicalPath
        {
            get
            {
                if (_physicalPath == "")
                {
                    _physicalPath = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase;
					bool isDll = _physicalPath.EndsWith("DLL");
                    _physicalPath = System.IO.Path.GetDirectoryName(_physicalPath).Replace("file:\\", "");
					if (isDll && _physicalPath.EndsWith("bin"))
						_physicalPath = _physicalPath.Replace("bin", "");
                    if (_physicalPath.EndsWith("\\") == false)
                        _physicalPath = _physicalPath + "\\";
                }
                return _physicalPath;
            }
        }

		/// <summary>
		/// Return the default database as defined in the appSettings of the config file.
		/// </summary>
        public static string DefaultDB
        {
            get
            {
                if (_defaultDB == "")
                {
                    _defaultDB = CfgGetAppSetting("DefaultDB");
                }
                return _defaultDB;
            }
        }

		public static string DefaultMailTemplate
		{
			get
			{
				if (_defaultMailTemplate == "")
				{
					_defaultMailTemplate = PhysicalPath + CfgGetAppSetting("DefaultMailTemplate");
				}
				return _defaultMailTemplate;
			}
		}

		/// <summary>
		/// Create a random unique has code string that can be used in the system
		/// </summary>
		/// <param name="length"></param>
		/// <returns>random string of the given length</returns>
		public static string CreateHashCode(int length = 20)
		{
			string guidResult = string.Empty;

			while (guidResult.Length < length)
			{
				// Get the GUID.
				guidResult += Guid.NewGuid().ToString().GetHashCode().ToString("x");
			}

			// Make sure length is valid.
			if (length <= 0 || length > guidResult.Length)
				throw new ArgumentException("Length must be between 1 and " + guidResult.Length);

			// Return the first length bytes.
			return guidResult.Substring(0, length);
		}

	}
}
